/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.approvalformat.core.domain.manager;

import com.inspur.edp.web.approvalformat.api.entity.ApprovalFormat;
import com.inspur.edp.web.approvalformat.core.domain.converter.ApprovalFormatConverter;
import com.inspur.edp.web.approvalformat.core.domain.entity.ApprovalFormatDO;
import com.inspur.edp.web.approvalformat.core.domain.repository.ApprovalFormatRepository;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * @author Xu‘fa Wang
 * @date 2020/5/16 20:44
 */
public class ApprovalFormatManager {
    private final ApprovalFormatRepository repository;

    public ApprovalFormatManager(ApprovalFormatRepository repository) {
        this.repository = repository;
    }

    /**
     * 根据 bizEntity id 获取审批格式
     *
     * @param bizEntityId     业务实体id
     * @param firstDimension  审批格式第一维度
     * @param secondDimension 审批格式第二维度
     * @return 审批格式集合
     */
    public List<ApprovalFormat> getApprovalFormatByBeIdWithFirstDimensionAndSecondDimension(String bizEntityId, String firstDimension, String secondDimension) {
        List<ApprovalFormatDO> list = null;

        if (firstDimension == null || firstDimension.isEmpty()) {
            if (secondDimension == null || secondDimension.isEmpty()) {
                list = this.repository.findAllByBeIdAndDim1IsNullAndDim2IsNull(bizEntityId);
            } else {
                //throw new RuntimeException("第一维度为空时，第二维度必须为空。请联系开发人员处理");
                list = this.repository.findAllByBeIdAndDim1IsNullAndDim2IsNull(bizEntityId);
            }
        } else {
            if (secondDimension == null || secondDimension.isEmpty()) {
                list = this.repository.findAllByBeIdAndDim1AndDim2IsNull(bizEntityId, firstDimension);
            } else {
                list = this.repository.findAllByBeIdAndDim1AndDim2(bizEntityId, firstDimension, secondDimension);
                //尝试查找firstDimension-public
                if (list == null || list.size() <= 0) {
                    list = this.repository.findAllByBeIdAndDim1AndDim2IsNull(bizEntityId, firstDimension);
                }
            }

            // 如果根据第一维度或第二维度未获取到数据，则尝试基于beId取数
            if (list == null || list.size() <= 0) {
                list = this.repository.findAllByBeIdAndDim1IsNullAndDim2IsNull(bizEntityId);
            }
        }

        return ApprovalFormatConverter.toVo(list);
    }

    /**
     * 根据 billCategory id 和维度获取审批格式
     *
     * @param billCategoryId  单据种类id
     * @param firstDimension  审批格式第一维度
     * @param secondDimension 审批格式第二维度
     * @return 审批格式集合
     */
    public List<ApprovalFormat> getApprovalFormatByBillCategoryIdWithFirstDimensionAndSecondDimension(String billCategoryId, String firstDimension, String secondDimension) {
        List<ApprovalFormatDO> list = null;

        if (firstDimension == null || firstDimension.isEmpty()) {
            if (secondDimension == null || secondDimension.isEmpty()) {
                list = this.repository.findAllByBillCategoryIdAndDim1IsNullAndDim2IsNull(billCategoryId);
            } else {
                //throw new RuntimeException("第一维度为空时，第二维度必须为空。请联系开发人员处理");
                list = this.repository.findAllByBillCategoryIdAndDim1IsNullAndDim2IsNull(billCategoryId);
            }
        } else {
            if (secondDimension == null || secondDimension.isEmpty()) {
                list = this.repository.findAllByBillCategoryIdAndDim1AndDim2IsNull(billCategoryId, firstDimension);
            } else {
                list = this.repository.findAllByBillCategoryIdAndDim1AndDim2(billCategoryId, firstDimension, secondDimension);
                //尝试查找firstDimension-public
                if (list == null || list.size() <= 0) {
                    list = this.repository.findAllByBillCategoryIdAndDim1AndDim2IsNull(billCategoryId, firstDimension);
                }
            }
            // 扩展找不到，返回基础
            if (list == null || list.size() <= 0) {
                list = this.repository.findAllByBillCategoryIdAndDim1IsNullAndDim2IsNull(billCategoryId);
            }
        }

        return ApprovalFormatConverter.toVo(list);
    }

    /**
     * 根据 billCategory id 获取审批格式
     *
     * @param billCategoryId 单据种类id
     * @return 审批格式集合
     */
    public List<ApprovalFormat> getApprovalFormatByBillCategoryId(String billCategoryId) {
        List<ApprovalFormatDO> list = this.repository.findAllByBillCategoryId(billCategoryId);
        return ApprovalFormatConverter.toVo(list);
    }

    /**
     * 根据 billCategory id 获取审批格式并根据维度排序
     *
     * @param billCategoryId 单据种类id
     * @return 审批格式集合
     */
    public List<ApprovalFormat> getApprovalFormatByBillCategoryIdAndOrderByDimension(String billCategoryId) {
        // TODO: 使用 JPA 方式实现排序
        List<ApprovalFormatDO> list = this.repository.findAllByBillCategoryIdAndOrderByDimension(billCategoryId);
        return ApprovalFormatConverter.toVo(list);
    }

    /**
     * 根据 formId id 获取审批格式
     *
     * @param formId 表单id
     * @return 审批格式集合
     */
    public List<ApprovalFormat> getApprovalFormatByFormId(String formId) {
        if (formId == null || formId.isEmpty()) {
            return null;
        }
        List<ApprovalFormatDO> list = this.repository.findAllByFormId(formId);
        return ApprovalFormatConverter.toVo(list);
    }

    /**
     * 根据 id 获取审批格式
     *
     * @param id 审批格式id
     * @return 审批格式实例
     */
    public ApprovalFormat getApprovalFormatById(String id) {
        Optional<ApprovalFormatDO> optional = this.repository.findById(id);
        if (!optional.isPresent()) {
            return null;
        }

        ApprovalFormatDO entity = optional.get();
        return ApprovalFormatConverter.toVo(entity);
    }

    /**
     * 删除审批格式实例
     *
     * @param id 审批格式id
     */
    public void deleteApprovalFormatById(String id) {
        if (id == null) {
            return;
        }

        this.repository.deleteById(id);
    }

    /**
     * 添加审批格式实例
     *
     * @param relation 审批格式DO
     * @return ApprovalFormat 审批格式VO
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public ApprovalFormat add(ApprovalFormatDO relation) {
        ApprovalFormatDO entity = this.repository.save(relation);
        return ApprovalFormatConverter.toVo(entity);
    }

    /**
     * 更新审批格式的formUrl
     *
     * @param relation 审批格式DO
     * @return ApprovalFormat 审批格式VO
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public ApprovalFormat updateFormUrl(ApprovalFormatDO relation) {
        ApprovalFormatDO entity = this.repository.save(relation);
        return ApprovalFormatConverter.toVo(entity);
    }

    /**
     * 保存审批格式实例
     *
     * @param relation 审批格式DO
     * @return ApprovalFormat 审批格式VO
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public ApprovalFormat save(ApprovalFormatDO relation) {
        ApprovalFormatDO entity = this.repository.save(relation);
        return ApprovalFormatConverter.toVo(entity);
    }

    public boolean checkIfExistsById(String id) {
        return this.repository.existsById(id);
    }

    public boolean checkIfExistsByBillCategoryIdAndDimension(ApprovalFormatDO approvalFormatDO) {

        String firstDimension = approvalFormatDO.getDim1();
        String secondDimension = approvalFormatDO.getDim2();
        String billCategoryId = approvalFormatDO.getBillCategoryId();
        List<ApprovalFormatDO> list = null;

        if (firstDimension == null || firstDimension.isEmpty()) {
            if (secondDimension == null || secondDimension.isEmpty()) {
                list = this.repository.findAllByBillCategoryIdAndDim1IsNullAndDim2IsNull(billCategoryId);
            } else {
                list = this.repository.findAllByBillCategoryIdAndDim1IsNullAndDim2IsNull(billCategoryId);
            }
        } else {
            if (secondDimension == null || secondDimension.isEmpty()) {
                list = this.repository.findAllByBillCategoryIdAndDim1AndDim2IsNull(billCategoryId, firstDimension);
            } else {
                list = this.repository.findAllByBillCategoryIdAndDim1AndDim2(billCategoryId, firstDimension, secondDimension);
            }
        }
        return list.size() > 0;
    }

    public boolean checkIfExistsByViewModelId(ApprovalFormatDO approvalFormatDO) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("voId", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.EXACT))
                .withIgnorePaths("id", "beId", "dim1", "dim2", "formId", "billCategoryId", "formUrl");
        Example<ApprovalFormatDO> example = Example.of(approvalFormatDO, matcher);
        return this.repository.exists(example);
    }

}
